﻿using leetcodeAnswer.Answer;
using leetcodeAnswer.Code;
using leetcodeAnswer.Code.Ex;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace leetcodeAnswer
{
    class Program
    {
        #region 配置参数
        /// <summary>
        /// 所有答案特性集
        /// </summary>
        static List<AnswerAttribute> ListAnswer = new List<AnswerAttribute>();

        /// <summary>
        /// 当前页
        /// </summary>
        static int Index = 1;
        /// <summary>
        /// 每页显示数
        /// </summary>
        static int PageIndex = 20;
        /// <summary>
        /// 总行数
        /// </summary>
        static int MaxRow { get { return ListAnswer.Count; } }
        /// <summary>
        /// 总页数
        /// </summary>
        static int MaxPage { get { return PageIndex + (MaxRow % PageIndex == 0 ? 0 : 1); } }

        static int Error = 0;
        static bool Stop = false;
        #endregion

        static void Main(string[] args)
        {
            string nameSpace = "leetcodeAnswer.Answer";

            RunAnswer(nameSpace, 4);

            //LoadAnswer(nameSpace);

            //while (!Stop)
            //{
            //    View();

            //    Console.WriteLine("命令说明:P [参数](跳转页数)、R [参数](运行答案)\t（参数是数字）");
            //    string param = Console.ReadLine();


            //    if (int.TryParse(param.Substring(1), out int value))
            //    {
            //        if(value <= 0)
            //        {
            //            Error |= (int)ErrorType.Parameter;
            //        }

            //        switch (param[0])
            //        {
            //            case 'P':
            //                Index = value;
            //                break;
            //            case 'R':
            //                RunAnswer(nameSpace, value);
            //                Stop = true;
            //                break;
            //            default:
            //                Error |= (int)ErrorType.Parameter;
            //                break;
            //        }
            //    }
            //    else
            //    {
            //        Error |= (int)ErrorType.Parameter;
            //    }
            //}
            Console.Read();
        }

        /// <summary>
        /// 展示视图控制
        /// </summary>
        /// <returns></returns>
        static void View() {
            Console.Clear();
            Console.WriteLine("-----------------------------------------------");

            ListAnswer.Skip((Index - 1) * PageIndex).Take(PageIndex).OrderBy(o => o.Index).ToList().ForEach(o => {
                Console.WriteLine($"{o.Index}\t{o.Name}");
            });

            Console.WriteLine("-----------------------------------------------");

            Console.WriteLine($"当前第{Index}页,共{MaxPage}页{MaxRow}条数据");

            if((Error & (int)ErrorType.Parameter) == (int)ErrorType.Parameter)
            {
                Console.WriteLine("参数错误！");
            }
        }

        /// <summary>
        /// 加载所有答案
        /// </summary>
        /// <param name="nameSpace">运行目标命名空间</param>
        /// <returns></returns>
        static void LoadAnswer(string nameSpace)
        {
            ListAnswer.Clear();

            Assembly asm = Assembly.GetExecutingAssembly();

            foreach (Type type in asm.GetTypes())
            {
                if (type.Namespace == nameSpace)
                {
                    if (type.IsDefined(typeof(AnswerAttribute), false))
                    {
                        ListAnswer.Add(type.GetCustomAttribute<AnswerAttribute>(false));
                    }
                }
            }
        }

        /// <summary>
        /// 执行答案
        /// </summary>
        /// <param name="nameSpace">运行目标命名空间</param>
        /// <param name="answerIndex">运行答案的索引编号</param>
        static void RunAnswer(string nameSpace, int answerIndex)
        {
            Console.Clear();

            Assembly asm = Assembly.GetExecutingAssembly();
            
            foreach (Type type in asm.GetTypes())
            {
                if (type.Namespace == nameSpace)
                {
                    if(type.IsDefined(typeof(AnswerAttribute), false))
                    {
                        AnswerAttribute answerAttribute = type.GetCustomAttribute<AnswerAttribute>(false);

                        if (answerAttribute.Index != answerIndex)
                            continue;

                        Console.WriteLine(answerAttribute.Print());
                        
                        MethodInfo run = null;
                        PropertyInfo pamater = null;

                        foreach (MethodInfo item in type.GetMethods())
                        {
                            if (item.IsDefined(typeof(AnswerRunAttribute), false))
                            {
                                run = item;
                            }
                        }
                        
                        foreach(PropertyInfo item in type.GetProperties())
                        {
                            if (item.IsDefined(typeof(AnswerParameterAttribute), false))
                            {
                                pamater = item;
                            }
                        }

                        if(run != null && pamater != null)
                        {
                            object example = asm.CreateInstance(type.FullName);

                            foreach(var pamater_item in pamater.GetValue(example) as List<object[]>)
                            {
                                try
                                {
                                    Console.WriteLine("输入参数");
                                    Console.WriteLine(JsonConvert.SerializeObject(pamater_item));
                                    Console.WriteLine("运行结果:");
                                    Console.WriteLine(
                                        JsonConvert.SerializeObject(run.Invoke(example, pamater_item)));
                                    Console.WriteLine("-----------------------------------------------");
                                }
                                catch(Exception ex)
                                {
                                    Console.WriteLine($"出错了：\t{ex.Message}");
                                }
                            }
                            return;
                        }
                    }
                }
            }
            Console.WriteLine("未找到可执行的答案");
        }
    }

    enum ErrorType
    {
        /// <summary>
        /// 参数错误
        /// </summary>
        Parameter = 1
    }
}
